/**********************************************************************************************************************
 * @file    nmea_rmc.c
 * @author  Queclink Jason.Huang
 * @date    2018-10-09
 * @brief   NMEA-RMC frame source.
 *
 * Copyright (C) 2018 Queclink Wireless Solutions (ShenZhen) Co., Ltd. All Rights Reserved.
 *
 * @attention
 *
 * @usage
 *
 *********************************************************************************************************************/

/* includes ---------------------------------------------------------------------------------------------------------*/
#include <stdlib.h>
#include <string.h>
#include "nmea.h"

/* ----------------------------------------------------------------------------------------------------------------- */

/*
 * @brief  转换nmea消息中的utc时间和日志字符串
 * @note
 * @param  utc: [O], 保存转换后的utc时间
 *         time: [I], 时间字符串
 *         date: [I], 日期字符串
 * @retval none
 */
void nmea_string_time_to_utc(struct tm *utc, char* time, char *date)
{
    utc->tm_sec = 10 * (time[4] - '0') + (time[5] - '0');
    if (utc->tm_sec > 60 || utc->tm_sec < 0)
        utc->tm_sec = 0;
    utc->tm_min = 10 * (time[2] - '0') + (time[3] - '0');
    if (utc->tm_min > 59 || utc->tm_min < 0)
        utc->tm_min = 0;
    utc->tm_hour = 10 * (time[0] - '0') + (time[1] - '0');
    if (utc->tm_hour > 23 || utc->tm_hour < 0)
        utc->tm_hour = 0;
    utc->tm_mday = 10 * (date[0] - '0') + (date[1] - '0');
    if (utc->tm_mday > 31 || utc->tm_mday < 1)
        utc->tm_mday = 1;
    utc->tm_mon = (10 * (date[2] - '0') + (date[3] - '0')) - 1;
    if (utc->tm_mon > 11 || utc->tm_mon < 0)
        utc->tm_mon = 0;
    utc->tm_year = (10 * (date[4] - '0') + (date[5] - '0')) + 100;
    if (utc->tm_year > 300 || utc->tm_year < 0)
        utc->tm_year = 0;
}


/*
 * @brief  将字符串中的经纬度转换为数值
 * @note
 * @param  srcLongitude: [I], 待转换的经度字符串
 *         srcLatitude: [I], 待转换的纬度字符串
 *         is_east_longitude: [I], 传入的经度是否为东经
 *         is_north_latitude: [I], 传入的纬度是否为北纬
 *         longitude: [O], 转换后得到的经度值
 *         latitude: [O], 转换后得到的纬度值
 * @retval none
 */
void nmea_latitude_longitude_convert_format(char *srcLongitude, char *srcLatitude, char is_east_longitude, char is_north_latitude,
                                                            double *longitude, double *latitude)
{
    int degree;
    double tmp;

    tmp = atof(srcLongitude);                                   /*经度转换*/
    degree = (int)(tmp / 100);                                  /*得到度      */
    *longitude = degree + (tmp - 100 * degree) / 60.0;
    *longitude = (is_east_longitude)? *longitude:-(*longitude); /*东西经判断 */

    tmp = atof(srcLatitude);                                    /*纬度转换*/
    degree = (int)(tmp / 100);
    *latitude = degree + (tmp - 100 * degree) / 60.0;
    *latitude = (is_north_latitude)? *latitude :-(*latitude);   /*南北纬判断  */
}


extern bool gsa_update;

/*
 * @brief  RMC消息解析
 * @note
 * @param  argc: [I], 消息分割后字符串数量
 *         argv: [I], 字符串地址列表
 * @retval none
 */
void nmea_rmc_parse(int argc, char *argv[])
{

    char temp_time[14];
    char temp_date[10];
    nmea_protocol_parse_t *nmea_ptr;
    gnss_task_manage_t * gnss_manage = get_gnss_manage();

    gsa_update = true;

    nmea_ptr = get_nmea_manage_context();
    if (NULL == nmea_ptr)
        return;

    nmea_ptr->recv_nmea_msg |= RMC_MASK;

    for (int i=0; i< SV_MAX; i++) {
        if (0 == (gnss_manage->sat_update_mask&(0x1<<i)) && gnss_manage->sat[i].count != 0)
            gnss_manage->sat[i].count = 0;          /* 未获取则清除 */
    }
    gnss_manage->sat_update_mask = 0;

    /*定位状态 A=定位, V=未定位*/
    if (strncmp(argv[2], "A", 1) == 0)
        nmea_ptr->stream_valid_mask |= RMC_MASK;
    else
        nmea_ptr->stream_valid_mask &= (~RMC_MASK);

    /* 字段1为时间(格式为hhmmss.xxx)
     * 字段9为日期(格式为ddmmyy) */
    if (strlen(argv[1]) != 0 && strlen(argv[9]) != 0){
        memset(temp_time, 0, sizeof(temp_time));
        memset(temp_date, 0, sizeof(temp_date));
        strncpy(temp_time, argv[1], sizeof(temp_time));
        strncpy(temp_date, argv[9], sizeof(temp_date));
        nmea_string_time_to_utc(&(nmea_ptr->raw_info.utc), temp_time, temp_date);

        if (strlen(argv[1])>=9)
            nmea_ptr->raw_info.utc_ms = (argv[1][7]-'0')*100 + (argv[1][8]-'0')*10;
        else
            nmea_ptr->raw_info.utc_ms = 0;
    }else{
        memset(&nmea_ptr->raw_info.utc, 0, sizeof(nmea_ptr->raw_info.utc));
        nmea_ptr->raw_info.utc_ms = 0;
    }

    /*经纬度格式转换*/
    if (strlen(argv[3]) != 0 && strlen(argv[5]) != 0){
        nmea_latitude_longitude_convert_format(argv[5], argv[3],
                          strncmp(argv[6], "E", 1) == 0 ,
                          strncmp(argv[4], "N", 1) == 0 ,
                          &(nmea_ptr->raw_info.longitude),
                          &(nmea_ptr->raw_info.latitude));
    }else{
        nmea_ptr->raw_info.longitude = 0;
        nmea_ptr->raw_info.latitude = 0;
    }
    /*速度*/
    if(strlen(argv[7]) != 0){
        nmea_ptr->raw_info.speed = (atof(argv[7])*1.852);
        gnss_manage->gnss_info.speed_is_absent = false;
    }else{
        nmea_ptr->raw_info.speed = 0;
        gnss_manage->gnss_info.speed_is_absent = true;
    }
    /*角度*/
    if(strlen(argv[8]) != 0){
        nmea_ptr->raw_info.angle =(float) atof(argv[8]);
        gnss_manage->gnss_info.angle_is_absent = false;
    }else{
        nmea_ptr->raw_info.angle = 0;
        gnss_manage->gnss_info.angle_is_absent = true;
    }
    if(!gnss_manage->gnss_info.is_uart_rx_ok){
        gnss_manage->gnss_info.is_uart_rx_ok = true;
    }
    /* 获取 */
    if (strlen(argv[12]) != 0) {
        switch (argv[12][0]) {
        case 'N':
            nmea_ptr->raw_info.posmode = POSMODE_N;
            break;
        case 'E':
            nmea_ptr->raw_info.posmode = POSMODE_E;
            break;
        case 'A':
            nmea_ptr->raw_info.posmode = POSMODE_A;
            break;
        case 'D':
            nmea_ptr->raw_info.posmode = POSMODE_D;
            break;
        default:
            nmea_ptr->raw_info.posmode = POSMODE_N;
            break;
        }
    } else {
        gnss_manage->gnss_info.raw_info.posmode = POSMODE_N;
    }
}
